/**
 * @date 2005-12-12 9:52:43
 *
 */
package org.nanhill.xsheet.output.excel;

import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;
import org.nanhill.commons.model.table.Cell;
import org.nanhill.commons.model.table.Row;
import org.nanhill.commons.model.table.Table;
import org.nanhill.xsheet.XSheetParseException;
import org.nanhill.xsheet.model.XSheetModelHelper;
import org.nanhill.xsheet.model.XSheetStyle;

/**
 * @author alin
 * 
 */
public class DefaultExcelOutputBuilder extends ExcelOutputBuilder {
	private Map<Integer, HSSFCellStyle> styleMap;

	private static final Map<String, Short> colorMap = Xhtml2Hssf.getColorMap();

	private static final Map<String, Short> posMap = Xhtml2Hssf
			.getPositionMap();

	private static short getBgColor(String colorName) {
		return colorMap.get(colorName);
	}

	private static short getAlignment(String pos) {
		return posMap.get(pos);
	}

	private HSSFCellStyle getDefaultStyle() {
		HSSFCellStyle hssfStyle = this.workbook.createCellStyle();
		hssfStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		hssfStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		hssfStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		hssfStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
		return hssfStyle;
	}

	@Override
	protected void buildWorkbook() throws XSheetParseException {
		this.workbook = new HSSFWorkbook();
	}

	protected void buildStyle() throws XSheetParseException {
		this.styleMap = new HashMap<Integer, HSSFCellStyle>();
		HSSFCellStyle hssfStyle = this.getDefaultStyle();
		// set default hssf style with style id equals 0
		this.styleMap.put(0, hssfStyle);
		XSheetStyle[] styles = this.model.getStyles();
		for (XSheetStyle style : styles) {
			int styleId = style.getId();
			// add style if style is not null and style id is positive integer
			if (null != style && 0 < styleId) {
				hssfStyle = this.getDefaultStyle();
				String attr = style.getBgColor();
				if (null != attr) {
					hssfStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
					hssfStyle.setFillForegroundColor(getBgColor(attr));
				}
				attr = style.getAlignment();
				if (null != attr) {
					hssfStyle.setAlignment(getAlignment(attr));
				}
				this.styleMap.put(styleId, hssfStyle);
			}
		}
	}

	protected void buildPushCellSheet() throws XSheetParseException {
		XSheetModelHelper.transferPushToFixedInEachRow(this.model);
		XSheetModelHelper.transferPushToFixedBetweenRows(this.model);
		this.buildFixedCellSheet();
	}

	protected void buildFixedCellSheet() throws XSheetParseException {
		Object[] tables = model.getTables().toArray();
		for (int k = 0; k < tables.length; k++) {
			Table table = (Table) tables[k];
			HSSFSheet sheet = this.workbook.createSheet(table.getName());
			Object[] rows = table.getRows().toArray();
			for (int i = 0; i < rows.length; i++) {
				Row row = (Row) rows[i];
				HSSFRow excelRow = sheet.createRow((short) i);
				Object[] cells = row.getCells().toArray();
				for (int j = 0; j < cells.length; j++) {
					Cell cell = (Cell) cells[j];
					HSSFCell excelCell = excelRow.createCell((short) j);
					if (null != cell) {
						String value = cell.getValue();
						excelCell.setEncoding(HSSFCell.ENCODING_UTF_16);
						excelCell.setCellValue(value);
						int styleId = cell.getStyleId();
						HSSFCellStyle hssfStyle = this.styleMap.get(styleId);
						if (null == hssfStyle)
							throw new XSheetParseException(
									"hssf style not exist: style id = "
											+ styleId + "; cell value = "
											+ value);
						excelCell.setCellStyle(hssfStyle);
						int colspan = cell.getColspan();
						int rowspan = cell.getRowspan();
						if (1 < rowspan || 1 < colspan) {
							// notice, here is (j + span - 1) not j + span
							sheet.addMergedRegion(new Region(i, (short) j, i
									+ rowspan - 1, (short) (j + colspan - 1)));
						}
					} else {
						excelCell.setCellStyle(this.getDefaultStyle());
					}

				}
			}
		}
	}



}
